package me.flyray.bsin.server.biz;


import com.alibaba.cloud.ai.advisor.RetrievalRerankAdvisor;
import com.alibaba.cloud.ai.memory.redis.RedisChatMemoryRepository;
import com.alibaba.cloud.ai.model.RerankModel;
import me.flyray.bsin.domain.entity.AgentCard;
import me.flyray.bsin.domain.enums.AIAgentChoreographyType;
import me.flyray.bsin.domain.request.AppChatDTO;
import me.flyray.bsin.infrastructure.mapper.AgentCardMapper;
import me.flyray.bsin.server.ws.WsServerEndpoint;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.memory.MessageWindowChatMemory;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.ai.tool.ToolCallbackProvider;
import org.springframework.ai.vectorstore.SearchRequest;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Map;

@Service
public class AppAgentEngine {

    private final ChatModel chatModel;
    private final VectorStore vectorStore;
    private final RerankModel rerankModel;
    private final ToolCallbackProvider tools;
    private final MessageWindowChatMemory messageWindowChatMemory;
    private final int MAX_MESSAGES = 100;

    @Value("classpath:/prompts/system-qa.st")
    private Resource systemResource;
    @Value("classpath:/prompts/BI.txt")
    private Resource biTxt;

    public AppAgentEngine(@Qualifier("dashscopeChatModel") ChatModel chatModel, VectorStore vectorStore, RerankModel rerankModel, @Qualifier("loadbalancedMcpAsyncToolCallbacks") ToolCallbackProvider tools, RedisChatMemoryRepository redisChatMemoryRepository) {
        this.chatModel = chatModel;
        this.vectorStore = vectorStore;
        this.rerankModel = rerankModel;
        this.tools = tools;
        this.messageWindowChatMemory = MessageWindowChatMemory.builder()
                .chatMemoryRepository(redisChatMemoryRepository)
                .maxMessages(MAX_MESSAGES)
                .build();;

    }

    @Autowired
    private AgentCardMapper agentCardMapper;


    /**
     * 1、根据不同的智能体参数，获取ChatClient，根据模型和工具
     * 2、进行模型推理对话
     * @param wsServerEndpoint
     * @param agentCard
     * @param aiChatDTOReq
     */
    public void handleSingleAgent(WsServerEndpoint wsServerEndpoint, AgentCard agentCard, AppChatDTO aiChatDTOReq){

        String message = aiChatDTOReq.getQuestion();
        if ("图表".equals(message)){
            String promptTemplate = getPromptTemplate(biTxt);
            wsServerEndpoint.sendMessageAsync(promptTemplate);
            return;
        }

        // TODO 不同的智能体类型，客户端不同
        ChatClient chatClient = getChatClient(AIAgentChoreographyType.SINGLE_AGENT,"");

        // TODO 不同智能体不同参数
        ChatResponse chatResponse = chatClient.prompt()
                .user(message).call()
                .chatResponse();
        System.out.println(chatResponse.getResult().getOutput().getText());

        wsServerEndpoint.sendMessageAsync(chatResponse.getResult().getOutput().getText());

        // 不同的chatType处理不同： 流式，非流式
//        chatClient.prompt()
//                .user(message)
//                .stream()
//                .chatResponse()
//                .subscribe(chatResponse -> {
//                    String content = chatResponse.getResult().getOutput().getText();
//                    // 在这里处理每个文本片段
//                    System.out.println("流式回复片段: " + content);
//                    // 发送消息
//                    wsServerEndpoint.sendMessageAsync(content);
//                }, error -> {
//                    System.err.println("发生错误: " + error);
//                }, () -> {
//                    System.out.println("流已完成。");
//                });

    }

    public void handleMultiAgent(WsServerEndpoint wsServerEndpoint, AgentCard agentCard, AppChatDTO aiChatDTOReq){

        // 发送消息
        wsServerEndpoint.sendMessageAsync("您好，有什么可以帮您的？");
    }

    public String handleSingleAgent(Map<String, Object> requestMap){

        // 发送消息
        return null;
    }

    public String handleMultiAgent(Map<String, Object> requestMap){

        // 发送消息
        return null;
    }

    /**
     * 处理聊听内容
     * @param aiChatDTOReq
     * @param webSocketServer
     */
    public void chat(AppChatDTO aiChatDTOReq, WsServerEndpoint webSocketServer) {
        // 根据toNo查找对应智能体
        AgentCard agentCard = new AgentCard();
        agentCard.setAgentType("1");
        AIAgentChoreographyType aiAgentType = AIAgentChoreographyType.getInstanceById(agentCard.getAgentType());
        // 判断枚举什么类型，不同的类型做不同的处理
        switch (aiAgentType) {
            case SINGLE_AGENT:
                // 单智能体处理逻辑
                handleSingleAgent(webSocketServer, agentCard, aiChatDTOReq);
                break;
            case MULTI_AGENT:
                // 多智能体处理逻辑
                handleMultiAgent(webSocketServer, agentCard, aiChatDTOReq);
                break;
            default:
                throw new IllegalArgumentException("未知的智能体类型: " + aiAgentType.getDesc());
        }
    }

    /**
     * 根据类型获取 ChatClient
     */
    private ChatClient getChatClient(AIAgentChoreographyType type, String message) {

        SearchRequest searchRequest = SearchRequest.builder().
                topK(4)
                .similarityThresholdAll()
                .query(message)
//                .filterExpression(new FilterExpressionBuilder().eq(textField, message).build())
                .build();

        // Step3 - Retrieve and llm generate
        String promptTemplate = getPromptTemplate(systemResource);

        ChatClient chatClient = ChatClient.builder(chatModel)
                .defaultToolCallbacks(tools)
//                .defaultOptions(OpenAiChatOptions.builder()
//                // 是否需要工具
//                .internalToolExecutionEnabled(false).build())
//                .defaultAdvisors(new RetrievalRerankAdvisor(vectorStore, rerankModel, searchRequest, new SystemPromptTemplate(promptTemplate), 0.1))
                .defaultAdvisors(new RetrievalRerankAdvisor(vectorStore, rerankModel, searchRequest))
                .build();
        // 发送消息
        return chatClient;
    }

    private String getPromptTemplate(Resource systemResource) {
        try {
            return systemResource.getContentAsString(StandardCharsets.UTF_8);
        }
        catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

}
